1. Technical Field
A “Memory Allocation Visualizer” provides various techniques for generating dynamic, interactive, customizable animated visualizations of memory allocation event trace information recorded or captured during program execution.
2. Background
Due to the large performance gap between processor speeds and memory and disk access times, a program's memory system performance is one of the key determinants of its overall performance. The memory system behavior of software is determined by a complex set of factors that include code and data size, program data structures used, mapping of code and data to memory addresses, how they are accessed, and architectural considerations such as the sizes of caches and main memory. Consequently, programmers often have little idea of a program's memory systems behavior and often write programs with poor memory system performance.
As is well known to those skilled in the art, among the most common problems in the memory performance of various software elements are “memory fragmentation” and “memory leaks.” Memory fragmentation involves a failure to reuse memory that has been freed. Excessive fragmentation can lead to more costly paging behavior (i.e., more page faults, and consequently, more slow disk accesses). Memory leaks involve a failure to free memory that is no longer in use. Memory leaks can lead to running out of memory, increased paging activity, software crashes, degraded OS performance, etc. In addition, there is a wide variety of program behaviors, such as repeated reallocation of the same memory, too large memory footprint, too many small allocations, etc., that can result in poor memory performance.
Some of these memory allocation problems can be discovered using conventional static analysis tools. Unfortunately, conventional static analysis tools are known to report many false positives with respect to suspected memory usage problems. Moreover, programmers are often interested in optimizing program performance for specific scenarios and want to understand the dynamic behavior of the program over time for the scenarios of interest. However, analysis of the dynamic behavior is problematic when looking at any given point in time during the execution of the program, because of lack of knowledge of future events. For example, what appears to be a potential fragmentation or leak problem could change in the future when that memory block is reused or freed. Static analysis tools simply do not provide sufficient information for properly evaluating these types of dynamic memory scenarios.
Use of type-safe managed languages such as Java or C# eliminates many memory leaks. However, leaks are still possible because of unnecessary object references. In addition, use of managed languages is not generally considered appropriate for performance-critical software because it increases overhead and decreases the programmer's ability to do low-level optimization of data structures. Hence, unmanaged languages such as C or C++ continue to be used for performance-critical software. While a number of recent memory allocation visualization efforts address object reference patterns in managed languages, they are of less value for understanding memory allocation problems in unmanaged languages.
Significant research has been done on memory analysis and visualization tools. For example, two basic approaches are often used to analyze memory problems. Static analysis tools, mentioned above, catch potential problems without executing the program. While these do not cause any runtime overhead, they tend to have many false positives because they lack detailed information only available from observing the dynamic behavior of the running program.
In contrast, dynamic analysis tools do monitor the dynamic behavior by instrumenting the program, thus yielding better analysis results at the cost of significant runtime overhead. Statistical and sampling approaches reduce that overhead while retaining the benefits of dynamic analysis. To reduce the overhead even further, various techniques use ECC-Memory hardware to monitor memory use. For managed languages, several dynamic analysis tools use object reference graphs to discover unneeded references to objects. These include an automated analysis tool for Java™ programs, and object ownership profiling. However, all these tools look for specific memory problems (typically memory leaks) and do not support memory behavior exploration or detection of memory fragmentation.
Visualization has been used for dynamic memory analysis in a number of ways. One of the earliest examples displayed a map of memory in a 2D layout, color coded memory blocks by data type, and used animation to show the changes to memory over time. A related technique also used a 2D map, but used the x-axis to represent time and the y-axis to represent memory address. In this system, color coding was used to show different data attributes. However, these conventional systems do not support a variety of views, filters and features that are generally sufficient to enable memory behavior exploration and easy detection of common memory problems such as leaks and fragmentation.
In fact, while early visualization systems focused on memory events, much of the later work focused on higher level object ownership. This is especially apparent in various techniques for leak detection for managed languages. For example, one such system helps to discover unneeded references to stale objects in Java™ programs by constructing and visualizing object reference graphs. A related system visualized type points-from graphs to find unneeded references to objects in garbage-collected languages. Yet another conventional process operated by constructing and visualized a simplified memory ownership graph to reveal memory problems in the Java™ heap. However, these techniques are of limited utility for unmanaged languages.